<?php

namespace App\Task;

use App\Model\Applet;
use App\Model\DataUserBackhaul;
use GuzzleHttp\Client;
use Hyperf\Crontab\Annotation\Crontab;
use Hyperf\DbConnection\Db;
use Hyperf\Logger\LoggerFactory;
use Hyperf\Utils\ApplicationContext;
use Psr\Log\LoggerInterface;

//#[Crontab(name: "BackhaulUser", rule: "*/10 * * * * *", callback: "execute", memo: "获取新注册的用户'")]
class BackhaulUserTask
{
    protected LoggerInterface $logger;

    public static $token = '7FE11418980F94B82110648EC0DAFD2B';

    public static $reportUrl = "https://clue.oceanengine.com/outer/wechat/applet/token/1779984845733000";

    public static $startReportUrl = "https://ad.oceanengine.com/track/activate/";

    public function __construct(protected LoggerFactory $loggerFactory)
    {
        $this->logger = $this->loggerFactory->get('log', 'backhaulUser');
    }

    public function execute()
    {
        $this->logger->info(date('Y-m-d H:i:s') . '------------------------获取新注册的用户');
        //获取需要获取任务的视频
        $container = ApplicationContext::getContainer();
        $redis = $container->get(\Hyperf\Redis\RedisFactory::class)->get('default');
        $nowTime = date('Y-m-d H:i:s',time());
        $beforeTime = date('Y-m-d H:i:s',time()-(86400*2));
        $selectTime = date('Y-m-d H:i:s',time()-1000);

        $handleKey = 'backhaul_user_or_or_or_or_live_live_or';
        try {

            $this->logger->info('获取所有拥有的用户');

            $keyData = $redis->get($handleKey);
            if(!empty($keyData)){

                $this->logger->info('存在处理中的用户进程');
                $this->logger->info(date('Y-m-d H:i:s') . '------------------------结束定时获取用户进行上报');
                return;
            }else{
                $redis->set($handleKey,1);
            }

            $appletData = Applet::query()->where(['type' => '1'])->whereNotNull('AppKey')->select(['id'])->get();
            if($appletData->isNotEmpty()){

                foreach ($appletData as $appletDatum) {
                    try {
                        $applet_id = $appletDatum->id;
                        $this->logger->info('查询这个小程序的用户表',[$applet_id]);
                        $userData =Db::table('data_user_'.$applet_id.' as user')
                            ->select(['user.id',
                                'user.xc_open_id',
                                'user.ad_id',
                                'user.is_backhaul',
                                'user.unionid',
                                'user.clue_token',
                                'user.click_id',
                                'data_spread.id as data_spread_id','data_spread.user_type as data_spread_user_type','data_spread.spread_platform_id as data_spread_spread_platform'])
//                        ->where(['user.is_backhaul' => 'N'])
//                        ->where(['user.is_handle' => 'N'])
                            ->where('user.spread_id','!=' ,0)
                            ->leftJoin('data_spread','user.spread_id','=','data_spread.id')
                            ->whereBetween('user.dyeing_time',[$selectTime,$nowTime])->get();
                    }catch (\Exception $e){
                        $this->logger->info('查询这个的用户表,错误：',[$e->getMessage()]);
                        continue;
                    }
                    if($userData->isNotEmpty()){
                        $this->logger->info('查询这个的用户表,用户数量为：',[$userData->count()]);

                        foreach ($userData as $userDatum){
                            $data_spread_user_type = $userDatum->data_spread_user_type;
                            $data_spread_spread_platform = $userDatum->data_spread_spread_platform;
                            $spread_id = $userDatum->data_spread_id;

                            //查询用户针对此推广链接回传过
                            $userCount = DataUserBackhaul::query()
                                ->where('user_id', $userDatum->id)
                                ->where('applet_id', $applet_id)
                                ->where('spread_id', $spread_id)
                                ->count('id');
                            if($userCount > 0){
                                continue;
                            }

                            //星图用户
                            if($data_spread_spread_platform == 2){

                                //没有计划ID
                                if(!empty($userDatum->click_id)) {
                                    $this->logger->info('用户上报clickID ',[$userDatum->id]);
                                    $clue_token = '';
                                    $unionid = '';
                                    $xc_open_id = '';
                                    $click_id = $userDatum->click_id;
                                    //普通用户
                                    $registerData = $this->uploadRegister($clue_token,$unionid,$xc_open_id,$click_id,$data_spread_spread_platform);
                                    if($registerData){
                                        $this->logger->info('用户上报星图计划成功，存入关联表 ',[$userDatum->id]);
                                        DataUserBackhaul::create([
                                            'applet_id' => $applet_id,
                                            'user_id' => $userDatum->id,
                                            'spread_id' => $spread_id,
                                            'clue_token' => $clue_token,
                                            'unionid' => $unionid,
                                            'xc_open_id' => $xc_open_id,
                                            'click_id' => $click_id,
                                            'user_type' => $data_spread_spread_platform,
                                        ]);
                                        Db::table('data_user_'.$applet_id)->where(['id' => $userDatum->id])->update(['is_handle' => 'Y','is_backhaul' => 'Y']);
                                    }else{
                                        $this->logger->error('用户上报星图失败，部分值为空',[$clue_token,$unionid,$xc_open_id,$click_id]);
                                    }

                                }else{
                                    $this->logger->info('用户没有click ID ',[$userDatum->id]);
                                    Db::table('data_user_'.$applet_id)->where(['id' => $userDatum->id])->update(['is_handle' => 'Y']);
                                }

                            }else{
                                //没有计划ID
                                if(empty($userDatum->ad_id)) {
                                    $this->logger->info('用户没有计划ID ',[$userDatum->id]);
                                    Db::table('data_user_'.$applet_id)->where(['id' => $userDatum->id])->update(['is_handle' => 'Y']);

                                }else{

                                    if($userDatum->clue_token == 'undefined') {
                                        $this->logger->info('用户clue_token有问题 ', [$userDatum->id]);
                                        Db::table('data_user_' . $applet_id)->where(['id' => $userDatum->id])->update(['is_handle' => 'Y']);
                                        continue;
                                    }


                                    $this->logger->info('用户上报计划ID ',[$userDatum->id]);
                                    $clue_token = $userDatum->clue_token;
                                    $unionid = $userDatum->unionid;
                                    $xc_open_id = $userDatum->xc_open_id;
                                    $click_id = $userDatum->click_id;
                                    //普通用户
                                    $registerData = $this->uploadRegister($clue_token,$unionid,$xc_open_id,$click_id,$data_spread_spread_platform);
                                    if($registerData){
                                        $this->logger->info('用户上报计划成功，存入关联表 ',[$userDatum->id]);
                                        DataUserBackhaul::create([
                                            'applet_id' => $applet_id,
                                            'user_id' => $userDatum->id,
                                            'spread_id' => $spread_id,
                                            'clue_token' => $clue_token,
                                            'unionid' => $unionid,
                                            'xc_open_id' => $xc_open_id,
                                            'click_id' => $click_id,
                                            'user_type' => $data_spread_spread_platform,
                                        ]);
                                        Db::table('data_user_'.$applet_id)->where(['id' => $userDatum->id])->update(['is_handle' => 'Y','is_backhaul' => 'Y']);
                                    }else{
                                        $this->logger->error('用户上报计划失败，部分值为空',[$clue_token,$unionid,$xc_open_id,$click_id]);
                                    }
                                }
                            }
                        }
                    }else{
                        $this->logger->error('没有用户需要上报');
                    }
                }
            }else{
                $this->logger->info('没有微信的小程序');
            }
            $redis->del($handleKey);
        }catch (\Exception $e){
            $redis->del($handleKey);
            $this->logger->error('请求上报出现问题|错误：' . $e->getLine() . '|' . $e->getMessage());
        }
        $this->logger->info(date('Y-m-d H:i:s') . '------------------------结束获取新注册的用户');
    }
    public function getSign($nonce,$timestamp){
        $token = self::$token;
        $collect = [$token,$nonce,$timestamp];
        //获取token
        usort($collect,'strcmp');
        $signature = sha1(implode('',$collect));

        return $signature;
    }
    public function uploadRegister($clue_token,$union_id,$open_id,$clickid,$data_spread_spread_platform){

        try {

        //头条
            if($data_spread_spread_platform == 1){

                if(empty($clue_token) || empty($union_id)|| empty($open_id)|| empty($clickid)){
                    return false;
                }

                $params = [
                    "clue_token" => $clue_token,
                    "union_id"  => $union_id,
                    "open_id"  => $open_id,
                    "event_type"  => "0",
                ];
                $nonce = rand();
                $timestamp = time();
                $signature = $this->getSign($nonce,$timestamp);
                $linkUrl = self::$reportUrl.'?timestamp='.$timestamp.'&nonce='.$nonce.'&signature='.$signature;
                $this->logger->info('请求上报数据：'.PHP_EOL.var_export(['result' => $params], true));
                $this->logger->info('请求上报Url：'.$linkUrl);
                //开始上传
                $result  = $this->request($params, $linkUrl,'POST');
                if($result['status'] == 200 ){
                    $this->logger->info('调用上报接口成功 返回数据：'.PHP_EOL.var_export(['result' => $result], true));
                    return true;
                }else{
                    $this->logger->error('调用上报接口失败 返回数据：'.PHP_EOL.var_export(['result' => $result], true));
                }
                //星图
            }else{

                if(empty($clickid)){
                    return false;
                }

                $params = [
                    "callback" => $clickid,
                    "event_type"  => "0",
                ];
                $this->logger->info('关闭星图上报功能');
                return true;


    //            $linkUrl = self::$startReportUrl;
                $linkUrl = self::$startReportUrl.'?callback='.$clickid.'&event_type=0';
                $this->logger->info('请求星图上报数据：'.PHP_EOL.var_export(['result' => $params], true));
                $this->logger->info('请求星图上报Url：'.$linkUrl);
                //开始上传
    //            $result  = $this->request($params, $linkUrl,'GET');
                $result = $this->http_curl($linkUrl,'GET');
                if($result['code'] == 0 ){
                    $this->logger->info('调用星图接口成功 返回数据：'.PHP_EOL.var_export(['result' => $result], true));
                    return true;
                }else{
                    $this->logger->error('调用星图接口失败 返回数据：'.PHP_EOL.var_export(['result' => $result], true));
                }

            }
        }catch (\Exception $e){
            $this->logger->error('回传报错跳过|错误：' . $e->getLine() . '|' . $e->getMessage());
            return false;
        }

        return false;
    }

    /**
     * 传入数组进行HTTP POST请求
     */
    function request(array $params, string $url,string $method)
    {
        $client   = new Client([
            'timeout' => 3
        ]);
        $headers       =['Content-Type' => 'application/json;charset=utf-8', 'Accept' => 'application/json','Accept-Charset' => 'utf-8'];
        $requestParams = [
            'headers' => $headers,
        ];
        if ($method == 'GET') {
            $requestParams['query'] = $params;
        } else {
            $requestParams['json'] = $params;
        }
//        var_dump($requestParams);
        $response = $client->request($method,$url, $requestParams);
        if ($response->getStatusCode() !== 200) {
            return '';
        }
        $result   = $response->getBody()->getContents();
        $resultArr = json_decode($result,true);
        return $resultArr;

    }

    public function http_curl($url,$type='get',$res='json',$arr='')
    {
        //1.初始化curl
        $ch = curl_init();
        //2.设置curl的参数
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        if ($type == 'post') {
            curl_setopt($ch, CURLOPT_POST, 1);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $arr);
        }
        curl_setopt($ch,CURLOPT_TIMEOUT,10);
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
        //3.采集
        $output = curl_exec($ch);

        //如果返回的值，是json格式，则转换成数组
        if ($res == 'json') {
            if (curl_errno($ch)) {
                //请求失败，返回错误信息
                $reutrn = curl_error($ch);
                curl_close($ch);
                return $reutrn;

            } else {
                $reutrn = json_decode($output, true);
                curl_close($ch);
                //请求成功
                return $reutrn;
            }
        }
    }
}